/******************************************************************************
 * * hal_bt.h - implementation of different hardware devices interface
 *
 * *(C) Copyright 2019 Asr International Ltd.
 * * All Rights Reserved
 * ******************************************************************************/

#ifndef HAL_BT_H_
#define HAL_BT_H_

#ifdef __cplusplus
extern "C" {
#endif
#include "hal.h"
#include "lv_conf.h"

#if USE_LV_BLUETOOTH != 0
#include "bt_inc/bt_api.h"
#include "bt_inc/bt_mgr.h"
#include "bt_inc/bt_api_hfp.h"
#include "bt_inc/bt_api_obex.h"
#include "bt_inc/bt_api_avrcp.h"
#if USE_LV_WATCH_DEMO != 0
#include "../../lv_watch/include/ui_inter_msg_interface.h"
#include "../../lv_watch/include/ui_nvm_interface.h"
#endif
#if USE_LV_PHONE != 0
#include "../../lv_phone/include/ui_inter_msg_interface.h"
#include "../../lv_phone/include/ui_nvm_interface.h"
#endif

#define COD_TYPE_HEADSET    0x400
#define COD_TYPE_PHONE      0x200
#define BT_PAIRED_NUM       10
#define BT_SCAN_NUM         2 * BT_PAIRED_NUM
#define BT_INQUIRY_TIME_DELAY  2000
#define HAL_BT_VOLUME_MAX   15
#define FS_MAX_CHUNK_SIZE BT_OBEX_FRAME_SIZE

#define SD_FS_LETTER      'D'
#define FILE_ROOT_DIR     "D:\\*"
#define FILE_TEXT_DIR     "D:/text/"
#define FILE_IMAGE_DIR    "D:/image/"
#define FILE_MUSIC_DIR    "D:/music/"
#define FILE_VIDEOS_DIR   "D:/videos/"
#define FILE_DIR          "D:/"

enum {
    #if USE_LV_WATCH_DEMO != 0
    MMI_BT_SWITCH_ON_CNF = UI_MSG_BT_ADP_BASE,
    #endif
    #if USE_LV_PHONE != 0
    MMI_BT_SWITCH_ON_CNF = UI_MSG_SETTING_BASE,//0x900
    #endif
    MMI_BT_SWITCH_OFF_CNF,
    MMI_BT_INQUIRY_CNF,
    MMI_BT_PAIR_CNF,
    MMI_BT_ACL_CONNECT_CNF,
    MMI_BT_A2DP_CONNECT_CNF,
    MMI_BT_A2DP_MEDIA_CONNECT_CNF,
    MMI_BT_AVRCP_CONNECT_CNF,
    MMI_BT_AVRCP_KEY_CNF,
    MMI_BT_HEADSET_CONNECT_CNF,

    //BT HFP profile ui messages
    MMI_BT_HFP_CONNECTED,
    MMI_BT_HFP_DISCONNECTED,
    MMI_BT_HFP_ATA,
    MMI_BT_HFP_ATCHUP,
    MMI_BT_HFP_DIAL,
    MMI_BT_HFP_ATCHLD,
    MMI_BT_HFP_VOICE_RECOGNITION,
    MMI_BT_HFP_SPEAKER_VOLUME,
    MMI_BT_HFP_MICROPHONE_GAIN,

    //BT OBEX file send message
    MMI_BT_OBEX_FILE_RECEIVE_START,
    MMI_BT_OBEX_FILE_RECEIVING,
    MMI_BT_OBEX_FILE_RECEIVE_FINISH,
    MMI_BT_OBEX_FILE_RECEIVE_ABORT,
    MMI_BT_OBEX_FILE_RECEIVE_START_AND_FINISH,

    MMI_BT_OBEX_FILE_SEND_FAILED,
    MMI_BT_OBEX_FILE_SEND_SUCCESS,
    MMI_BT_OBEX_FILE_SEND_START,
    MMI_BT_OBEX_FILE_SEND_CONTINUE,

    MMI_BT_SCO_DISCONNECTED
};

#if USE_LV_WLAN != 0
//received from hal_wlan for hw reset
enum {
    WLAN_BT_FIRMWARE_ASSERT = 0xFFFE,
    WLAN_BT_RECOVER_CONNECTION
};
#endif

enum {
    BT_INQUIRY_INIT = 0,
    BT_INQUIRY_INQUIRYING,
    BT_INQUIRY_CANCELING,
    BT_INQUIRY_COMPLETE,
    BT_INQUIRY_INTERRUPT
};
typedef UINT8 bt_inquiry_state;

enum {
    PROFILE_ACL         = 0,
    PROFILE_AVRCP,           //= 1,
    PROFILE_A2DP,            //= 2,
    PROFILE_HFP,         //= 3,
    PROFILE_SCO,         //= 4,
    PROFILE_OBEX,            //= 5,
    PROFILE_CONNECTION,  //= 6,
    PROFILE_PAIRED,      //= 7,
    PROFILE_A2DP_MEDIA,  //= 8,
    PROFILE_MAX
};
typedef UINT8 lv_bt_profile;

enum {
    PROFILE_STATE_UNKNOWN       = 0,
    PROFILE_STATE_CONNECTED     = 1,
    PROFILE_STATE_DISCONNECTED  = 2,
    PROFILE_STATE_CONNECTING    = 3,
    PROFILE_STATE_FAILED        = 4,
    PROFILE_STATE_MAX
};
typedef UINT8 lv_bt_profile_state;

typedef struct
{
    UINT8 name[MAX_BT_NAME];
    UINT8 length;
    UINT8 addr[6];
    UINT32 cod;
    UINT8 profile_status[PROFILE_MAX];
    BOOL auto_connect;
} bt_paired_dev_t;

enum {
    BT_RECEIVE_FINISH  = 1,
    BT_RECEIVE_ABORT,
    BT_RECEIVE_NO_SDCARD,
    BT_RECEIVE_NO_SPACE,
    BT_RECEIVE_SD_USING,
    BT_RECEIVE_MAX,
};

typedef struct {
    lv_fs_file_t fd;
    UINT32 file_size;
    UINT32 file_offset;
    UINT32 packet_data_len;
    VOID * packet_data;
    BOOL b_start_receive_data;
    INT8 file_name[MAX_BT_OBEX_FILE_NAME];
    UINT8 disconnect_reason;
} bt_file_receive_context;

typedef struct {
    lv_fs_file_t fd;
    UINT32 file_size;
    UINT32 file_offset;
    UINT32 chunk_size;
    UINT32 chunk_offset;
    UINT8 * chunk_buffer;
    INT8 file_name[MAX_BT_OBEX_FILE_NAME];
    struct bt_addr addr;
} bt_file_send_context;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    UINT8 connect;
    UINT8 for_audio;
} mmi_msg_bt_connect_response_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    UINT8 result;
} mmi_msg_bt_switch_response_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    UINT8 complete;
} mmi_msg_bt_inquiry_response_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    UINT8 name[MAX_BT_NAME];
    UINT8 addr[6];
    UINT8 linkey[16];
    UINT32 cod;
    UINT32 linkkey_type;
    UINT8 paired;
} mmi_msg_bt_pair_response_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    INT32 connect;
    INT32 reason;
    UINT8 addr[6];
    UINT16 handle;
} mmi_msg_bt_acl_response_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
} mmi_msg_bt_hfp_common_response_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    int32_t value;
} mmi_msg_bt_hfp_value_response_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    UINT8 addr[6];
    INT32 connect;
    INT32 cid;
} mmi_msg_bt_a2dp_response_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    UINT8 key_state; //0-pressed, 1-released
    UINT8 key;
} mmi_msg_bt_avrcp_key_t;

typedef struct
{
    UI_Inter_Msg_Header_t header;
    UINT8 data;
} mmi_msg_bt_obex_t;


/*
*  create bt task
*/
VOID bt_adp_task_create(VOID);

/*
*  destroy bt task
*/
VOID bt_adp_task_destroy(VOID);

/*
*  add device from scanlist to PairedList
*/
INT32 bt_add_device(struct bt_addr addr, UINT32 cod);

/*
*  connect device in the PairedList
*/
INT32 bt_connect_device(struct bt_addr addr, UINT32 cod);

/*
* disconnect device in PairedList only
*/
INT32 bt_disconnect_device(struct bt_addr addr, UINT32 cod);

/*
* accept device in PairedList only
*/
INT32 bt_accept_connect_device(struct bt_addr addr, UINT32 accept);

/*
* disconnect and remove pairing info
*/
INT32 bt_remove_device(struct bt_addr addr, UINT32 cod);

/*
* scan available device
*/
INT32 bt_inquiry_device(VOID);

/*
* cancel scan available device
*/
INT32 bt_inquiry_device_cancel(VOID);

/*
* pairing device from scan list
*/
INT32 bt_bonding_device(struct bt_addr addr, UINT32 cod);

/*
* pairing device accept
*/
INT32 bt_accept_bonding_device(struct bt_addr addr, UINT32 accept);

/*
* unpairing device
*/
INT32 bt_unbond_device(struct bt_addr addr);

/*
* open bt device
*/
INT32 bt_open_device(VOID);

/*
* close bt device
*/
INT32 bt_close_device(VOID);

/*
* change device local name
*/
INT32 bt_change_local_devname(const INT8 * name);

/*
* get bt device open state
*/
BOOL bt_get_state(VOID);

/*
* create scanlist & pairedlist
*/
VOID bt_list_init(VOID);

/*
* destroy scanlist & pairedlist
*/
VOID bt_list_destroy(VOID);

/*
* clean scanlist
*/
VOID bt_clean_scan_list(void);

/*
* get headset connect state
*/
BOOL bt_get_headset_connect(VOID);

/*
* get headset hfp connect state
*/
BOOL bt_get_hfp_connect(VOID);

/*
* get current scan dev count
*/
UINT32 bt_get_scan_dev_cnt(VOID);

/*
* get current paired dev count
*/
UINT32 bt_get_paired_dev_cnt(VOID);

/*
* get current inquiry state
*/
UINT8 bt_get_inquiry_state(VOID);

/*
* get paired list
*/
bt_paired_dev_t * bt_get_paired_list(VOID);

/*
* get dev from scanlist by index
*/
struct bt_event_inquiry * bt_get_scan_dev(UINT8 index);

/*
* get scan list
*/
struct bt_event_inquiry * bt_get_scan_list(VOID);

/*
* file receive cancel
*/
VOID bt_file_receive_cancel(VOID);

/*
* file receive continue
*/
VOID bt_file_receive_continue(VOID);

/*
* file receive ok
*/
VOID bt_file_receive_ok(VOID);

/*
* set disconnect reason to clear received file
*/
VOID bt_clear_received_file(VOID);

/*
* get receive file info
*/
bt_file_receive_context * bt_get_receive_file_info(VOID);

/*
* get device name
*/
VOID bt_get_device_name(INT8 * name);

/*
* close bt if shutdown or restore
*/
VOID bt_power_off(VOID);

/*
* get send file info
*/
bt_file_send_context * bt_get_send_file_info(VOID);

/*
* prepare to send file
*/
VOID bt_send_file_pre(INT8 * file_name, struct bt_addr addr);

/*
* cancel send file
*/
INT32 bt_file_send_cancel(VOID);

void bt_pin_config(uint8_t on);
extern void Ningbo_Ldo_12_set(BOOL OnOff);
extern void Ningbo_Ldo_12_set_1_8(void);

void bt_config_firmware(void);

#if USE_LV_BLE_DEMO
extern void ble_init(void);
extern void ble_deinit(void);
#endif

#if USE_LV_WLAN != 0
extern void hal_wlan_proc_continue(void);
extern bool hal_wlan_hw_reset_start(void);
extern void hal_wlan_hw_reset_end(void);
extern bool hal_wlan_wait_for_reopen_for_hw_reset(void);
#endif

#endif /*USE_LV_BLUETOOTH*/
#ifdef __cplusplus
}
#endif

#endif/*HAL_BT_H_*/
